package com.geor.gcv.ict;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.nutz.lang.Lang;
import org.nutz.log.Loggers;
import org.slf4j.Logger;

public class DataLoader {

	static Logger log = Loggers.get();

	/** 包含各类训练数据的容器 */
	private static Map<String, Map<String, Set<DataMatrix>>> dataMapContainer = new HashMap<String, Map<String, Set<DataMatrix>>>();

	/** 训练文件根目录 */
	private static File root;

	private static DataLoader dataLoader;

	private DataLoader() {
	}

	public boolean containKey(String key) {
		return dataMapContainer.keySet().contains(key);
	}

	public static DataLoader getInstance() {
		synchronized (log) {
			if (null == dataLoader) {
				dataLoader = new DataLoader();
			}
			return dataLoader;
		}
	}

	/**
	 * 设置训练文件根目录
	 * 
	 * @param rootDir
	 */
	public void setRootDir(String rootDir) {
		// 跳过重复设置
		if (new File(rootDir).equals(root)) {
			return;
		}
		root = new File(rootDir);
		if (!root.exists()) {
			throw new RuntimeException(rootDir + " error !");
		}
		// 各类训练子目录
		File[] trainFolders = root.listFiles();
		for (File trainFolder : trainFolders) {
			Map<String, Set<DataMatrix>> dataMaps = new HashMap<String, Set<DataMatrix>>();
			File files[] = trainFolder.listFiles();
			if (Lang.isEmpty(files)) {
				log.warn(String.format("train folder: %s is empty", trainFolder.getAbsolutePath()));
				continue;
			}
			for (File file : files) {
				Map<String, Set<DataMatrix>> dataMap = DataMatrix.parsing(file);

				if (dataMap.isEmpty()) {
					continue;
				}

				mergeMap(dataMaps, dataMap);
			}
			dataMapContainer.put(trainFolder.getName(), dataMaps);
		}
	}

	/**
	 * 获取某类型的训练数据
	 * 
	 * @param name
	 * @return
	 */
	public Map<String, Set<DataMatrix>> load(String name) {
		if (dataMapContainer.containsKey(name)) {
			return dataMapContainer.get(name);
		}
		return null;
	}

	public Map<String, Set<DataMatrix>> mergeMap(Map<String, Set<DataMatrix>> d1, Map<String, Set<DataMatrix>> d2) {
		Set<String> newdataKeys = d2.keySet();
		for (String newdataKey : newdataKeys) {
			// key存在
			if (d1.containsKey(newdataKey)) {
				d1.get(newdataKey).addAll(d2.get(newdataKey));
			}
			// key不存在
			else {
				d1.put(newdataKey, d2.get(newdataKey));
			}
		}
		return d1;
	}

}
